/*
 *  RIBuildIndexSVPR.java
 *
 */

package at.ofai.gate.riplugin2;


import gate.*;
import gate.creole.*;
import gate.creole.metadata.*;
import gate.util.GateRuntimeException;
import java.io.IOException;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import pitt.search.semanticvectors.*;
import pitt.search.semanticvectors.vectors.VectorType;


// document names:
// gatedocid.sectionid where gatedocid is gatedocnr:gatedocname and
// sectionid is annotationnr:annotationname:fromoffset:tooffset


/** 
 * This PR must be run in a controller, not a corpus controller.
 */
@CreoleResource(name = "RIBuildIndexSVBasicPR 2",
    icon = "riindex",
    //helpURL = "http://gate.ac.uk/userguide/sec:somechapter:sometopic:somepos",
    comment = "Create a SV Bag-Of-Words Random Indexing Datastructure")
public class RIBuildIndexSVBasicPR
  extends RIBuildIndexSVPR
  implements ProcessingResource
{

  @CreoleParameter(comment = "The SemanticVectors index LR to fill")
  @RunTime
  public void setIndexSVLR(RIIndexSVLR index) {
    this.indexSVLR = index;
  }
  public RIIndexSVLR getIndexSVLR() {
    return this.indexSVLR;
  }
  protected RIIndexSVLR indexSVLR = null;



  public static final Logger logger =
    Logger.getLogger(RIBuildIndexSVBasicPR.class.getName());

  /**
   * Run the index creation ....
   * 
   * @throws ExecutionException
   */
  @Override
  public void execute() throws ExecutionException {
    // check the directory URL and create the luceneIndexDir file
    luceneIndexDir = indexLuceneLR.getLuceneIndexDir();
    svTermIndex = indexSVLR.getSVTermIndex();
    svDocumentIndex = indexSVLR.getSVDocumentIndex();
    // TODO: check that the SV index dir exists
    // TODO: check that the lucene LR has data
    if(svTermIndex.exists()) {
      FileUtils.deleteQuietly(svTermIndex);
      logger.info("Existing SemanticVectors termvectors.bin file deleted");
    }
    if(svDocumentIndex.exists()) {
      FileUtils.deleteQuietly(svDocumentIndex);
      logger.info("Existing SemanticVectors docvectors.bin file deleted");
    }
    // create the SemanticVectors index files
    // For now the following parameters are fixed
    int dimensions = getVectorDimensions();
    int seedlength = getSeedDimensions();
    int minfrequency = getMinTermFrequency();
    int maxfrequency = Integer.MAX_VALUE;
    int maxnonalphabetchars = -1;
    String[] contentsfields = {"contents"};
    VectorStoreRAM initialdocvectors = null;
    TermVectorsFromLucene vecStore;
    //System.out.println("Creating elemental document vectors ...");
    try {
      Flags.dimension = dimensions;
      Flags.vectortype = "real";
      vecStore = TermVectorsFromLucene.createTermVectorsFromLucene(
              luceneIndexDir.getCanonicalPath(),
              VectorType.REAL, 
              dimensions, 
              seedlength, 
              minfrequency, 
              maxfrequency, 
              maxnonalphabetchars, 
              null, 
              contentsfields);
    } catch (Exception ex) {
      throw new GateRuntimeException("Exception elemental doc vectors: ",ex);
    }
    // Create doc vectors and write vectors to disk.
    DocVectors docVectors = null;
    try {
      //System.out.println("Creating document vectors ...");
      docVectors = new DocVectors(vecStore);
    } catch (IOException ex) {
      throw new GateRuntimeException("Exception creating doc vectors store",ex);
    }
    VectorStore writeableDocVectors = docVectors.makeWriteableVectorStore();
    try {
      //System.out.println("Writing term vectors to " + svTermIndex.getAbsolutePath());
      VectorStoreWriter.
              writeVectors(svTermIndex.getCanonicalPath(), vecStore);
      //System.out.println("Writing document vectors to " + svDocumentIndex.getAbsolutePath());
      VectorStoreWriter.
              writeVectors(svDocumentIndex.getCanonicalPath(), writeableDocVectors);
    } catch (Exception ex) {
      throw new GateRuntimeException("Exception writing doc or term vectors",ex);
    }
    // TODO: set the SV index LR to "having data"?
  }


  
} // class RIBuildSVPR
